package com.github.sbb.sherry.console.service.engine.config;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.sbb.sherry.common.base.Preconditions;
import com.github.sbb.sherry.common.base.ValidateResult;
import com.github.sbb.sherry.common.primitives.StringUtil;
import com.github.sbb.sherry.console.dto.PageList;
import com.github.sbb.sherry.console.exception.LogicException;
import com.github.sbb.sherry.primitives.config.datasource.DataSourceConfig;
import com.github.sbb.sherry.primitives.config.datasource.HttpDataSourceConfig;
import com.github.sbb.sherry.primitives.config.datasource.MongoDBDataSourceConfig;
import com.github.sbb.sherry.primitives.config.datasource.MySQLDataSourceConfig;
import com.github.sbb.sherry.primitives.config.datasource.RedisDataSourceConfig;
import com.github.sbb.sherry.repository.DatasourceRepository;
import com.github.sbb.sherry.repository.entity.Datasource;
import com.github.sbb.sherry.repository.enums.DatasourceStatusEnum;
import com.github.sbb.sherry.repository.enums.DatasourceTypeEnum;
import com.github.sbb.sherry.repository.enums.DeleteFlagEnum;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Service
public class DatasourceConfigService {

  @Autowired
  private DatasourceRepository datasourceRepository;

  public void addDatasource(final Datasource param) {
    Byte type = param.getType();
    ValidateResult validateResult = validateDatasourceConfig(type, param.getExpansionConfig());
    if (validateResult.isFailure()) {
      throw new LogicException(validateResult.getMessage());
    }

    String datasourceName = param.getName().trim();
    long count = datasourceRepository.countByName(datasourceName);
    Preconditions.checkArgument(count == 0, "已经有同名 datasource 无法添加");

    Datasource datasource = new Datasource();
    datasource.setName(datasourceName);
    datasource.setType(type);
    datasource.setDescription(param.getDescription());
    datasource.setDeleteFlag(DeleteFlagEnum.NOT_DELETED.getValue());
    datasource.setStatus(DatasourceStatusEnum.ACTIVE.getValue());
    datasource.setExpansionConfig(param.getExpansionConfig());

    datasourceRepository.addDatasource(datasource);
  }

  private ValidateResult validateDatasourceConfig(byte type, String expansionConfig) {

    DataSourceConfig dataSourceConfig = null;
    // TODO 如果写成 MAP 就不用这样判断了，先凑合吧
    if (type == DatasourceTypeEnum.HTTP.getValue()) {
      dataSourceConfig = JSON.parseObject(expansionConfig, HttpDataSourceConfig.class);
    } else if (type == DatasourceTypeEnum.MYSQL.getValue()) {
      dataSourceConfig = JSON.parseObject(expansionConfig, MySQLDataSourceConfig.class);
    } else if (type == DatasourceTypeEnum.REDIS.getValue()) {
      dataSourceConfig = JSON.parseObject(expansionConfig, RedisDataSourceConfig.class);
    } else if (type == DatasourceTypeEnum.MONGODB.getValue()) {
      dataSourceConfig = JSON.parseObject(expansionConfig, MongoDBDataSourceConfig.class);
    }

    if (dataSourceConfig != null) {
      return dataSourceConfig.validate();
    }
    return new ValidateResult(false, StringUtil.lenientFormat("没找到能和 Type: {} 想匹配的DataSourceConfig，请检查相关代码或者配置", type));
  }

  public PageList<Datasource> pageList(int currentPage, Integer pageSize) {
    if (pageSize == null) {
      pageSize = 10;
    }

    Page<Object> page = PageHelper.startPage(currentPage, pageSize);

    List<Datasource> activeDatasource = datasourceRepository.getActiveDatasource();

    return PageList.of(currentPage, pageSize, page.getTotal(), activeDatasource);
  }

  public List<Datasource> getByType(int type) {
    return datasourceRepository.getActiveDatasourceByType(type);
  }
}
